// VideoController.js - 视频控制器
const Video = require('../models/Video');
const { sequelize } = require('../config/db');
const redisUtil = require('../utils/redisUtil');
const { deleteCachePattern } = redisUtil;

class VideoController {
  /**
   * 获取推荐视频列表
   * @param {Object} req - 请求对象
   * @param {Object} res - 响应对象
   */
  static async getRecommendedVideos(req, res) {
    try {
      // 获取分页参数
      const { page = 1, pageSize = 10 } = req.query;
      
      // 验证参数
      const pageNum = parseInt(page, 10) || 1;
      const size = parseInt(pageSize, 10) || 10;
      
      // 获取视频列表（支持Redis缓存）
      const videos = await Video.getRecommendedVideos(pageNum, size);
      
      // 获取总数（用于计算总页数）
      const total = await Video.getTotalVideos();
      
      res.status(200).json({
        code: 200,
        message: '获取推荐视频成功',
        data: {
          list: videos,
          page: pageNum,
          pageSize: size,
          total,
          totalPages: Math.ceil(total / size),
          fromCache: videos.fromCache || false // 标识是否来自缓存
        }
      });
    } catch (error) {
      console.error('获取推荐视频失败:', error);
      res.status(500).json({
        code: 500,
        message: '获取推荐视频失败',
        error: error.message
      });
    }
  }

  /**
   * 获取热门视频列表
   * @param {Object} req - 请求对象
   * @param {Object} res - 响应对象
   */
  static async getHotVideos(req, res) {
    try {
      // 获取分页参数
      const { page = 1, pageSize = 10 } = req.query;
      
      // 验证参数
      const pageNum = parseInt(page, 10) || 1;
      const size = parseInt(pageSize, 10) || 10;
      
      // 获取视频列表（支持Redis缓存）
      const videos = await Video.getHotVideos(pageNum, size);
      
      // 获取总数（用于计算总页数）
      const total = await Video.getTotalVideos();
      
      res.status(200).json({
        code: 200,
        message: '获取热门视频成功',
        data: {
          list: videos,
          page: pageNum,
          pageSize: size,
          total,
          totalPages: Math.ceil(total / size),
          fromCache: videos.fromCache || false // 标识是否来自缓存
        }
      });
    } catch (error) {
      console.error('获取热门视频失败:', error);
      res.status(500).json({
        code: 500,
        message: '获取热门视频失败',
        error: error.message
      });
    }
  }

  /**
   * 获取最新视频列表
   * @param {Object} req - 请求对象
   * @param {Object} res - 响应对象
   */
  static async getLatestVideos(req, res) {
    try {
      // 获取分页参数
      const { page = 1, pageSize = 10 } = req.query;
      
      // 验证参数
      const pageNum = parseInt(page, 10) || 1;
      const size = parseInt(pageSize, 10) || 10;
      
      // 获取视频列表（支持Redis缓存，缓存时间较短）
      const videos = await Video.getLatestVideos(pageNum, size);
      
      // 获取总数（用于计算总页数）
      const total = await Video.getTotalVideos();
      
      res.status(200).json({
        code: 200,
        message: '获取最新视频成功',
        data: {
          list: videos,
          page: pageNum,
          pageSize: size,
          total,
          totalPages: Math.ceil(total / size),
          fromCache: videos.fromCache || false // 标识是否来自缓存
        }
      });
    } catch (error) {
      console.error('获取最新视频失败:', error);
      res.status(500).json({
        code: 500,
        message: '获取最新视频失败',
        error: error.message
      });
    }
  }

  /**
   * 获取幻灯片视频列表
   * @param {Object} req - 请求对象
   * @param {Object} res - 响应对象
   */
  static async getSlideVideos(req, res) {
    try {
      // 获取幻灯片视频（支持Redis缓存）
      const videos = await Video.getSlideVideos();
      
      res.status(200).json({
        code: 200,
        message: '获取幻灯片视频成功',
        data: videos
      });
    } catch (error) {
      console.error('获取幻灯片视频失败:', error);
      res.status(500).json({
        code: 500,
        message: '获取幻灯片视频失败',
        error: error.message
      });
    }
  }

  /**
   * 根据类别获取视频列表
   * @param {Object} req - 请求对象
   * @param {Object} res - 响应对象
   */
  static async getVideosByCategory(req, res) {
    try {
      // 获取类别ID和分页参数
      const { categoryId } = req.params;
      const { page = 1, pageSize = 10 } = req.query;
      
      // 验证参数
      if (!categoryId || isNaN(parseInt(categoryId, 10))) {
        return res.status(400).json({
          code: 400,
          message: '类别ID无效'
        });
      }
      
      const pageNum = parseInt(page, 10) || 1;
      const size = parseInt(pageSize, 10) || 10;
      
      // 获取视频列表（支持Redis缓存）
      const videos = await Video.getVideosByCategory(categoryId, pageNum, size);
      
      // 获取该类别下的视频总数
      const total = await Video.getTotalVideos({ categoryId });
      
      res.status(200).json({
        code: 200,
        message: '获取类别视频成功',
        data: {
          list: videos,
          page: pageNum,
          pageSize: size,
          total,
          totalPages: Math.ceil(total / size)
        }
      });
    } catch (error) {
      console.error('获取类别视频失败:', error);
      res.status(500).json({
        code: 500,
        message: '获取类别视频失败',
        error: error.message
      });
    }
  }

  /**
   * 获取视频详情
   * @param {Object} req - 请求对象
   * @param {Object} res - 响应对象
   */
  static async getVideoDetail(req, res) {
    try {
      // 获取视频ID
      const { id } = req.params;
      
      // 验证参数
      if (!id || isNaN(parseInt(id, 10))) {
        return res.status(400).json({
          code: 400,
          message: '视频ID无效'
        });
      }
      
      const videoId = parseInt(id, 10);
      
      // 获取视频详情（支持Redis缓存）
      const video = await Video.getVideoById(videoId);
      
      if (!video) {
        return res.status(404).json({
          code: 404,
          message: '视频不存在或已下架'
        });
      }
      
      // 更新观看次数（使用Redis计数器）
      try {
        await Video.updateViewCount(videoId);
        // updateViewCount方法内部已经会清除视频详情缓存，不需要在此处重复清除
      } catch (error) {
        console.error('更新观看次数失败:', error);
        // 即使更新失败，仍然返回视频详情，不影响用户体验
      }
      
      res.status(200).json({
        code: 200,
        message: '获取视频详情成功',
        data: video
      });
    } catch (error) {
      console.error('获取视频详情失败:', error);
      res.status(500).json({
        code: 500,
        message: '获取视频详情失败',
        error: error.message
      });
    }
  }

  /**
   * 直接从videos表获取视频的观看次数（仅用于测试）
   * @param {Object} req - 请求对象
   * @param {Object} res - 响应对象
   */
  static async getVideoViewCount(req, res) {
    try {
      const { id } = req.params;
      
      if (!id || isNaN(parseInt(id, 10))) {
        return res.status(400).json({
          code: 400,
          message: '视频ID无效'
        });
      }
      
      const videoId = parseInt(id, 10);
      
      // 尝试从Redis获取观看次数，如果不存在则查询数据库
      let viewCount;
      try {
        viewCount = await redisUtil.get(`video:view:${videoId}`);
        if (viewCount) {
          viewCount = parseInt(viewCount, 10);
        }
      } catch (redisError) {
        console.error('从Redis获取观看次数失败:', redisError);
      }
      
      // 如果Redis中没有，则直接查询数据库
      if (!viewCount) {
        const query = `SELECT view_count FROM videos WHERE id = :id`;
        const results = await sequelize.query(query, {
          replacements: { id: videoId },
          type: sequelize.QueryTypes.SELECT
        });
        
        if (results.length === 0) {
          return res.status(404).json({
            code: 404,
            message: '视频不存在'
          });
        }
        
        viewCount = results[0].view_count;
      }
      
      res.status(200).json({
        code: 200,
        message: '获取观看次数成功',
        data: {
          id: videoId,
          view_count: viewCount
        }
      });
    } catch (error) {
      console.error('获取观看次数失败:', error);
      res.status(500).json({
        code: 500,
        message: '获取观看次数失败',
        error: error.message
      });
    }
  }

  /**
   * 更新视频互动数的通用方法（更新后清除相关缓存）
   * @param {Object} req - 请求对象
   * @param {Object} res - 响应对象
   * @param {string} type - 互动类型（like或collect）
   */
  static async updateVideoInteraction(req, res, type) {
    try {
      const { id } = req.params;
      const { count } = req.body;
      
      // 验证参数
      if (!id || isNaN(parseInt(id, 10))) {
        return res.status(400).json({
          code: 400,
          message: '视频ID无效'
        });
      }
      
      if (typeof count !== 'number' || count === 0) {
        return res.status(400).json({
          code: 400,
          message: '更新数量必须是非零数字'
        });
      }
      
      const videoId = parseInt(id, 10);
      let result;
      
      // 根据类型调用不同的更新方法
      switch (type) {
        case 'like':
          result = await Video.updateLikeCount(videoId, count);
          break;
        case 'collect':
          result = await Video.updateCollectCount(videoId, count);
          break;
        default:
          return res.status(400).json({
            code: 400,
            message: '不支持的操作类型'
          });
      }
      
      if (result) {
        // 清除相关缓存
        try {
          await deleteCachePattern(`video:detail:${videoId}`);
          await deleteCachePattern('video:recommended:*');
          await deleteCachePattern('video:hot:*');
        } catch (cacheError) {
          console.error('清除缓存失败:', cacheError);
        }
        
        res.status(200).json({
          code: 200,
          message: `更新${type === 'like' ? '点赞' : '收藏'}数成功`
        });
      } else {
        res.status(404).json({
          code: 404,
          message: '视频不存在'
        });
      }
    } catch (error) {
      console.error(`更新视频${type === 'like' ? '点赞' : '收藏'}数失败:`, error);
      res.status(500).json({
        code: 500,
        message: `更新${type === 'like' ? '点赞' : '收藏'}数失败`,
        error: error.message
      });
    }
  }
}

module.exports = VideoController;